186. istio的Authorization policy(白名單)
前言
經過一個月的搬家事宜,
這篇應該是第一篇,之後還有許多東西,
都是這個月搬project碰到的。
正文
目的
只要設定白名單,限制某些ip能進入就好,
其他不用。
實作-Network
這邊使用istio 1.20 版本,雖然gateway API 剛出爐,
但我還沒去研究,所以下面用的都還是 istio API
首先確認你的LB類型,
直連(Network)的話,基本上沒太大問題,白名單很好設定。
-
開啓
externalTrafficPolicy":"Local"
,
兩種方法a. 手動改service
kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'
b. 加在istioOperator上面
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
service:
externalTrafficPolicy: Local
loadBalancerSourceRanges:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- Authorization設定
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: manage-ingress-policy
namespace: istio-system
spec:
selector:
matchLabels:
istio: ingressgateway
action: ALLOW
rules:
- from:
- source:
ipBlocks::
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
(注意,這邊的Load Balancer Type指的是Network,沒透過proxy的,
如果有開CDN,那就是istio說明上面的Load Balancer Type 是TCP Proxy)
實作-Proxy
這邊的網路走法是,有透過CDN,或是其他的prxoy代理連過來的服務。
numTrustedProxies 這個的值,取決於你的走法過了幾層的proxy,
我只有cdn轉島到gke上面的istio LB
-
設定方式
a. 在pod上面新增 anntations
metadata:
annotations:
"proxy.istio.io/config": '{"gatewayTopology" : { "numTrustedProxies": 1 } }'
b. 在istioOperator新增
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
defaultConfig:
gatewayTopology:
numTrustedProxies: 1
- Authorization設定
這邊有點坑,搞了一天才搞清楚。
強烈建議把istio的httpbin裝起來,實際去打,
然後一邊查看ingressgateway的deployment的log。
a. 限制全部
這是第一種方法,但這個只能針對『入口』的ingress做白名單驗證。
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: frontend-ingress-policy
namespace: istio-system
spec:
selector:
matchLabels:
app: ingressgateway-external
action: ALLOW
rules:
- from:
- source:
remoteIpBlocks:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
b. 針對單個
假如沒有在入口的話,無法照上面a.的方式抓到資料,
所以只能強制指定判斷header。
ref. Incorrect RemoteIP when Authorization Policy is applied to Injected Istio Proxy
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: frontend-ingress-policy
spec:
selector:
matchLabels:
group: frontend
action: ALLOW
rules:
- when:
- key: request.headers[X-Envoy-External-Address]
values:
- "10.*"
ref. Configuring Gateway Network Topology
Troubleshooting
istioOperator增加log 閱讀性
spec:
meshConfig:
accessLogFile: /dev/stdout
accessLogEncoding: JSON
accessLogFormat: |
{
"protocol": "%PROTOCOL%",
"upstream_service_time": "%REQ(X-ENVOY-UPSTREAM_SERVICE_TIME)%",
"upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%",
"duration": "%DURATION%",
"upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%",
"route_name": "%ROUTE_NAME%",
"downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%",
"user_agent": "%REQ(USER-AGENT)%",
"response_code": "%RESPONSE_CODE%",
"response_flags": "%RESPONSE_FLAGS%",
"start_time": "%START_TIME%",
"method": "%REQ(:METHOD)%",
"request_id": "%REQ(X-REQUEST-ID)%",
"upstream_host": "%UPSTREAM_HOST%",
"x_forwarded_for": "%REQ(X-FORWARDED-FOR)%",
"client_ip": "%REQ(TRUE-Client-IP)%",
"requested_server_name": "%REQUESTED_SERVER_NAME%",
"bytes_received": "%BYTES_RECEIVED%",
"bytes_sent": "%BYTES_SENT%",
"upstream_cluster": "%UPSTREAM_CLUSTER%",
"downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%",
"authority": "%REQ(:AUTHORITY)%",
"path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
"response_code_details": "%RESPONSE_CODE_DETAILS%"
}
ref. Understanding Istio Access Logs
Authorization Policy規則
- If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny.
如果有任何符合請求的自訂策略,則評估並拒絕請求,若評估結果為拒絕。
- If there are any DENY policies that match the request, deny the request.
如果有符合請求的任何拒絕策略,則拒絕該請求。
- If there are no ALLOW policies for the workload, allow the request.
如果工作負載沒有任何允許策略,則允許該請求。
- If any of the ALLOW policies match the request, allow the request.
如果有任何允許策略符合該請求,則允許該請求。
- Deny the request.
拒絕該請求。
ref. Authorization Policy
cloudflare轉發
上面有提到用cloudflare的CDN時,白名單會跟着變,
但在那之前還有個東西要注意,CDN轉發時,
cloudflare可以指定走http還是走https
這個會影響到istio的gateway,是開80還是443。